package com.yunquan.ohana.db

import android.annotation.SuppressLint
import android.content.ContentValues
import android.database.Cursor
import com.yunquan.ohana.entity.LocalFileEntity
import com.yunquan.ohana.entity.LocalLocationModel

class DBWeatherLocation {
    companion object {
        val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { DBWeatherLocation() }
    }

    private val readDB = DBManager.instance.readableDatabase
    private val writeDB = DBManager.instance.writableDatabase

    fun saveOrUpdate(data: LocalLocationModel): Boolean {
        return if (data.id != null) {
            update(data)
        } else {
            insert(data)
        }
    }

    fun insert(data: LocalLocationModel): Boolean {
        val result = writeDB.insert(DBManager.TABLE_WEATHER_LOCATION, null, toContentValues(data))
        return result != -1L
    }

    fun update(data: LocalLocationModel): Boolean {
        if (data.id == null) return false
        val result = writeDB.update(DBManager.TABLE_WEATHER_LOCATION, toContentValues(data), "id = ?", arrayOf(data.id.toString()))
        return result != 0
    }

    fun delete(id: Int): Boolean {
        val result = writeDB.delete(DBManager.TABLE_WEATHER_LOCATION, "id = ?", arrayOf(id.toString()))
        return result != 0
    }

    fun selectOne(
        selection: String? = null,
        selectionArgs: Array<String>? = null,
    ): LocalLocationModel? {
        val cursor = readDB.query(
            DBManager.TABLE_WEATHER_LOCATION,
            null,
            selection,
            selectionArgs,
            null,
            null,
            null,
        )
        var data: LocalLocationModel? = null
        if (cursor.moveToFirst()) {
            data = toEntity(cursor)
        }
        cursor.close()
        return data
    }

    fun selectAll(
        selection: String? = null,
        selectionArgs: Array<String>? = null,
    ): List<LocalLocationModel> {
        val cursor = readDB.query(
            DBManager.TABLE_WEATHER_LOCATION,
            null,
            selection,
            selectionArgs,
            null,
            null,
            null,
        )
        val data = mutableListOf<LocalLocationModel>()
        while (cursor.moveToNext()) {
            data.add(toEntity(cursor))
        }
        cursor.close()
        return data
    }

    @SuppressLint("Range")
    private fun toEntity(cursor: Cursor): LocalLocationModel {
        val id = cursor.getInt(cursor.getColumnIndex("id"))
        val userId = cursor.getString(cursor.getColumnIndex("user_id"))
        val locationId = cursor.getString(cursor.getColumnIndex("location_id"))
        val name = cursor.getString(cursor.getColumnIndex("name"))
        val longitude = cursor.getString(cursor.getColumnIndex("longitude"))
        val latitude = cursor.getString(cursor.getColumnIndex("latitude"))
        val timeZone = cursor.getString(cursor.getColumnIndex("time_zone"))
        val utcOffset = cursor.getString(cursor.getColumnIndex("utc_offset"))
        return LocalLocationModel(
            id = id,
            userId = userId,
            locationId = locationId,
            name = name,
            longitude = longitude,
            latitude = latitude,
            timeZone = timeZone,
            utcOffset = utcOffset,
        )
    }

    private fun toContentValues(data: LocalLocationModel): ContentValues {
        val values = ContentValues()
        if (data.id != null) {
            values.put("id", data.id)
        }
        if (data.userId != null) {
            values.put("user_id", data.userId)
        }
        if (data.locationId != null) {
            values.put("location_id", data.locationId)
        }
        if (data.name != null) {
            values.put("name", data.name)
        }
        if (data.longitude != null) {
            values.put("longitude", data.longitude)
        }
        if (data.latitude != null) {
            values.put("latitude", data.latitude)
        }
        if (data.timeZone != null) {
            values.put("time_zone", data.timeZone)
        }
        if (data.utcOffset != null) {
            values.put("utc_offset", data.utcOffset)
        }
        return values
    }
}